#include "stdafx.h"
#include "SceneLua.h"
#include "Entity/EntityManagerIf.h"
#include "Entity/EntityM.h"
#include "Entity/EntityN.h"
#include "Entity/EntityLua.h"

namespace SceneLua
{

bool push(lua_State* L, IScene* pScene)
{
	IScene** pp = (IScene**)lua_newuserdata(L, sizeof(IScene*));
	*pp = pScene;
	luaL_getmetatable(L, "woe.scene");
	if (lua_istable(L, -1))
	{
		lua_setmetatable(L, -2);
		return true;
	}
	else
	{
		LOG_ERROR("Failed to push IScene to lua, metatable not found!");
		return false;
	}
}

IScene* getUserData(lua_State* L)
{
	IScene**pp = (IScene**)luaL_checkudata(L, 1, "woe.scene");
	if (pp==NULL)
	{
		return NULL;
	}
	else
	{
		return *pp;
	}
}

int getID(lua_State* L)
{
	IScene* pScene = getUserData(L);
	if (pScene)
	{
		lua_pushinteger(L, pScene->getID());
		return 1;
	}
	return 0;
}

int setID(lua_State* L)
{
	IScene* pScene = getUserData(L);
	if (pScene)
	{
		int nID = lua_tointeger(L, 2);
		pScene->setStaticID(nID);
	}
	return 0;
}

int getStaticID(lua_State* L)
{
	IScene* pScene = getUserData(L);
	if (pScene)
	{
		int cid = pScene->getStaticID()>>24;
		int did = (pScene->getStaticID()>>16) & 0xff;
		int sid = (pScene->getStaticID()>>8) & 0xff;
		lua_pushinteger(L, cid);
		lua_pushinteger(L, did);
		lua_pushinteger(L, sid);
		return 3;
	}
	return 0;
}

int setStaticID(lua_State* L)
{
	IScene* pScene = getUserData(L);
	if (pScene)
	{
		int cid = lua_tointeger(L, 2);
		int did = lua_tointeger(L, 3);
		int sid = lua_tointeger(L, 4);
		
		pScene->setStaticID(cid<<24 | did<<16 | sid<<8);
	}
	return 0;
}


int add_monster(lua_State* L)
{
	IScene* pScene = getUserData(L);
	if (pScene)
	{
		int nStaticID = luaL_checkint(L, 2);
		if (nStaticID!=0)
		{
			IEntityManager* pEttMgr = pScene->getEntityMgr();
			if (pEttMgr)
			{
				IEntity* pEntity = new EntityM;
				pEntity->setStaticID(nStaticID);
				pEttMgr->addEntity(0, pEntity);

				EntityLua::push(L, pEntity);
				return 1;
			}
		}
	}
	return 0;
}

int add_npc(lua_State* L)
{
	IScene* pScene = getUserData(L);
	if (pScene)
	{
		int nStaticID = luaL_checkint(L, 2);
		if (nStaticID!=0)
		{
			IEntityManager* pEttMgr = pScene->getEntityMgr();
			if (pEttMgr)
			{
				IEntity* pEntity = new EntityN;
				pEntity->setStaticID(nStaticID);
				pEttMgr->addEntity(0, pEntity);

				EntityLua::push(L, pEntity);
				return 1;
			}
		}
	}
	return 0;
}

int setProps(lua_State* L)
{
	IScene* pScene = getUserData(L);
	if (pScene)
	{
		short idx = lua_tointeger(L, 2);
		int val = lua_tointeger(L, 3);
		pScene->setProps(idx, val);
	}
	return 0;
}

int getProps(lua_State* L)
{
	IScene* pScene = getUserData(L);
	if (pScene)
	{
		short idx = lua_tointeger(L, 2);
		lua_pushinteger(L, pScene->getProps(idx));
	}
	return 1;
}


static const luaL_Reg scene_funcs[] = {
	{"getStaticID", getStaticID},
	{"setStaticID", setStaticID},
	{"getID", getID},
	{"setID", setID},
	{"addM", add_monster},
	{"addN", add_npc},
	{"setProps", setProps},
	{"getProps", getProps},
	{NULL, NULL}
};


int libaray(lua_State* L)
{
	luaL_newmetatable(L, "woe.scene");
	// fill member list into metatable
	luaL_register(L, NULL, scene_funcs);

	// metatable.__index = metatable
	lua_pushstring(L, "__index");
	lua_pushvalue(L, -2);
	lua_settable(L, -3);

	return 0;
}

} // end of scene lua
